#define  _CRT_SECURE_NO_WARNINGS 1
#include <string>
#include <iostream>
using namespace std;

class Product
{
public:
	void makePartA(const string& s)
	{
		partA = s;
	}
	void makePartB(const string& s)
	{
		partB = s;
	}
	void makePartC(const string& s)
	{
		partC = s;
	}

	void get()
	{
		cout << partA + partB + partC << endl;
	}
private:
	string partA;
	string partB;
	string partC;

};

class Builder
{
public:
	virtual ~Builder() {}
	virtual void buildPartA(const string& s) = 0;
	virtual void buildPartB(const string& s) = 0;
	virtual void buildPartC(const string& s) = 0;
	Product get()
	{
		return product;
	}
protected:
	Product product;
};

class ConcreteBuliderA : public Builder
{
public:
	void buildPartA(const string& s)
	{
		product.makePartA("ConcreteBuliderA " + s + " ");
	}
	void buildPartB(const string& s)
	{
		product.makePartB("ConcreteBuliderA " + s + " ");
	}
	void buildPartC(const string& s)
	{
		product.makePartC("ConcreteBuliderA " + s + " ");
	}

};

class ConcreteBuliderB : public Builder
{
public:
	void buildPartA(const string& s)
	{
		product.makePartA("ConcreteBuliderB " + s + " ");
	}
	void buildPartB(const string& s)
	{
		product.makePartB("ConcreteBuliderB " + s + " ");
	}
	void buildPartC(const string& s)
	{
		product.makePartC("ConcreteBuliderB " + s + " ");
	}

};

class Director
{
public:
	Director() :builder_(nullptr) {}
	Director(Builder* bulider) : builder_(bulider) {}

	~Director()
	{
		if (builder_)
		{
			delete builder_;
		}
	}

	void set(Builder* builder)
	{
		if (builder_)
		{
			delete builder_;
		}
		builder_ = builder;
	}
	Product createProduct()
	{
		builder_->buildPartA("bulid part a");
		builder_->buildPartB("bulid part b");
		builder_->buildPartC("bulid part c");

		return builder_->get();
	}
private:
	Builder* builder_;
};

//int main()
//{
//	Director(new ConcreteBuliderA()).createProduct().get();
//	Director(new ConcreteBuliderB()).createProduct().get();
//
//	return 0;
//}